package com.lovo.sheyingback.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lovo.sheyingback.bean.User;
import com.lovo.sheyingback.result.GlobalHandleException;
import com.lovo.sheyingback.result.Result;
import com.lovo.sheyingback.result.ResultCode;
import com.lovo.sheyingback.result.UserValid;
import com.lovo.sheyingback.service.UserService;
import com.lovo.sheyingback.util.JWTUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;
import java.lang.reflect.Method;

@Component
public class JWTInterceptor implements HandlerInterceptor {
    @Autowired
    private UserService userService;

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("Authorization");// 从 http 请求头中取出 token

        // 如果不是映射到方法直接通过
        if(!(handler instanceof HandlerMethod)){
            return true;
        }
        HandlerMethod handlerMethod=(HandlerMethod)handler;
        Method method=handlerMethod.getMethod();
        //检查是否有UserValid注释，没有则跳过认证
        if(!method.isAnnotationPresent(UserValid.class)
                && !handlerMethod.getBeanType().isAnnotationPresent(UserValid.class)){
            return true;
        }
        if(token == null){
            writeValueAsString(response, Result.fail(ResultCode.USER_NOT_LOGGED_IN));
            return false;
        }
        String username;
        try {
            if(!token.startsWith("Bearer ")){
                writeValueAsString(response, Result.fail(ResultCode.USER_NOT_LOGGED_IN));
                return false;
            }
            token = token.substring(7);
            username = JWTUtil.getAudience(token);
        } catch (GlobalHandleException | NumberFormatException e) {
            writeValueAsString(response, Result.fail(ResultCode.USER_NOT_LOGGED_IN));
            return false;
        }
        User user = userService.getByUsername(username);
        if(user == null){
            writeValueAsString(response,Result.fail(ResultCode.USER_NOT_EXIST));
            return false;
        }
        // 验证 token
        try {
            JWTUtil.verifyToken(token,user.getPwd());
        } catch (GlobalHandleException e) {
            writeValueAsString(response,Result.fail(e.getResultCode()));
            return false;
        }
        request.setAttribute("user",user);
        return true;

    }
    private void writeValueAsString(HttpServletResponse response, Result result) throws IOException {

        ObjectMapper mapper = new ObjectMapper();
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().print(mapper.writeValueAsString(result));

    }

}
